<template>
    <transition name="scale-origin-animation">
        <div class="pdialog-mask" v-if="modelValue" :style="`z-index:${maxZindex}`">
            <div class="pdialog" ref="pdialog" @mousedown="mouseDownEve" :style="`width:${getWidth};height:${getHeight};`">
                <div class="pdialog-action" :style="`top:${actionTop};right:${actionRight};`">
                    <div class="pdialog-action-max" @click="isMax = !isMax">
                        <i :class="isMax ? 'fa fa-compress' : 'fa fa-expand'"></i>
                    </div>
                    <div class="pdialog-action-close" @click="closeDialog">
                        <i class="el-icon-close"></i>
                    </div>
                </div>
                <div class="pdialog-box">
                    <div class="pdialog-box-title" v-if="showTitle">
                        <slot name="title">
                            <div>{{ title }}</div>
                        </slot>
                    </div>
                    <div class="pdialog-box-body" :style="bodyStyle">
                        <slot>
                            <div>
                                <!-- 内容 -->
                            </div>
                        </slot>
                    </div>
                    <div class="pdialog-box-foot" v-if="showFoot">
                        <slot name="foot">
                            <div class="pdialog-foot-default">
                                <div>
                                    <el-button type="info" @click="closeDialog">{{closeTxt}}</el-button>
                                </div>
                                <div>
                                    <el-button type="warning" @click="ok">{{ okTxt }}</el-button>
                                </div>
                            </div>
                        </slot>
                    </div>
                </div>
            </div>
        </div>
    </transition>
</template>

<script lang="ts">
import {
    computed,
    defineComponent,
    onMounted,
    reactive,
    ref,
    toRefs,
    watch,
} from "vue";
import { useStore } from "vuex";
import utils from "@/lib/utils";
import DragTool from "@/lib/DragTool";
import setCssVal from "@/lib/setCssVal";
/**
 * state 数据类型
 */
interface IState {
    maxZindex: number;
    isMax: boolean;
}
export default defineComponent({
    name: "PDialog",
    props: {
        modelValue: {
            type: Boolean,
            default: false,
        },
        width: {
            type: String,
            default: "65%",
        },
        height: {
            type: String,
            default: "70%",
        },
        actionTop: {
            type: String,
            default: "0",
        },
        actionRight: {
            type: String,
            default: "0",
        },
        maxWidth: {
            type: String,
            default: "90%",
        },
        maxHeight: {
            type: String,
            default: "95%",
        },
        x: {
            type: String,
            default: "50%",
        },
        y: {
            type: String,
            default: "50%",
        },
        /**
         * 顶部可拖动区域高度
         */
        dragHeight: {
            type: Number,
            default: 45,
        },
        drag: {
            type: Boolean,
            default: false,
        },
        title: {
            type: String,
            default: "标题",
        },
        closeTxt: {
            type: String,
            default: "取消",
        },
        okTxt: {
            type: String,
            default: "确定",
        },
        showTitle: {
            type: Boolean,
            default: true,
        },
        showFoot: {
            type: Boolean,
            default: false,
        },
        closed: {
            type: Function,
            default: () => {
                return () => false;
            },
        },
        ok: {
            type: Function,
            default: () => {
                return () => false;
            },
        },
    },
    emits: ["update:modelValue"],
    setup(props, { emit }) {
        const store = useStore();
        const { UIAuth, bodySize } = toRefs(store.state);
        const pdialog: any = ref<any>();
        const state = reactive<IState>({
            maxZindex: 100,
            isMax: false,
        });
        const dragTool: DragTool = new DragTool();
        /**
         * 获取最大 z-index
         */
        const getMaxZIndex = () => {
            const allEle: Element[] = [...document.all];
            let MaxZIndex = 0;
            allEle.forEach((item: Element) => {
                const itemZindex = window.getComputedStyle(item).zIndex;
                if (!utils.empty(itemZindex)) {
                    const zIndex = parseInt(itemZindex, 0);
                    if (zIndex > MaxZIndex) {
                        MaxZIndex = zIndex;
                    }
                }
            });
            state.maxZindex = MaxZIndex < 399 ? 399 : MaxZIndex + 1;
        };
        /**
         * 关闭当前
         */
        const closeDialog = () => {
            emit("update:modelValue", false);
            props.closed();
        };
        /**
         * 鼠标按下事件 mousedown
         */
        const mouseDownEve = (event: MouseEvent) => {
            if (props.drag && event.button === 0) {
                const dragDiv = pdialog as HTMLDivElement;
                const clikDivY = event.clientY - dragDiv.offsetTop;
                if (clikDivY <= props.dragHeight) {
                    dragTool.startDrag(dragDiv, event);
                }
            }
        };
        watch(
            () => props.x,
            (val) => {
                setCssVal.setCssVal("--p-origin-x", val);
            }
        );
        watch(
            () => props.y,
            (val) => {
                setCssVal.setCssVal("--p-origin-y", val);
            }
        );
        watch(
            () => props.modelValue,
            (val) => {
                if (val) {
                    getMaxZIndex();
                }
            }
        );
        onMounted(() => {
            setCssVal.setCssVal("--p-origin-x", props.x);
            setCssVal.setCssVal("--p-origin-y", props.y);
        });
        return {
            UIAuth,
            bodySize,
            ...toRefs(state),
            // 获取body style 样式
            bodyStyle: computed(() => {
                if (props.showTitle && props.showFoot) {
                    return `height:calc(100% - 100px);`;
                } else if (!props.showTitle && props.showFoot) {
                    return `height:calc(100% - 60px);`;
                } else if (props.showTitle && !props.showFoot) {
                    return `height:calc(100% - 40px);`;
                } else {
                    return `height:100%;`;
                }
            }),
            getWidth: computed(() => {
                return state.isMax ? props.maxWidth : props.width;
            }),
            getHeight: computed(() => {
                return state.isMax ? props.maxHeight : props.height;
            }),
            closeDialog,
            mouseDownEve,
        };
    },
});
</script>


<style scoped lang="scss">
$pdialogAnimOriginX: var(--p-origin-x);
$pdialogAnimOriginY: var(--p-origin-y);
.pdialog {
    box-shadow: 0 0 15px $box-gray0-color;
    position: absolute;
    transition: all 0.3s ease-in;
    background-color: $white-color;
    z-index: 1;
    & * {
        transition: all 0.3s ease-in;
    }
    &-mask {
        position: fixed;
        z-index: 9999;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: rgba($color: #000000, $alpha: 0);
        display: flex;
        justify-content: center;
        align-items: center;
    }
    &-action {
        position: absolute;
        z-index: 1;
        display: flex;
        align-items: center;
        color: #ffffff;
        height: 40px;
        &-max,
        &-close {
            margin: 0 8px;
            cursor: pointer;
            &:hover {
                transform: scale(1.2);
            }
        }
        &-close {
            font-size: 20px;
        }
        &-max {
            font-size: 12px;
            width: 15px;
            height: 15px;
            border: 1px $background-color solid;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    }
    &-box {
        height: 100%;
        width: 100%;
        &-title {
            background-color: $primary-color;
            height: 40px;
            display: flex;
            align-items: center;
            padding: 0 10px;
            font-size: 14px;
            color: #ffffff;
            font-weight: bold;
        }
        &-body {
            overflow-x: hidden;
            overflow-y: auto;
            position: relative;
        }
        &-foot {
            height: 60px;
            //background-color: $primary-gray;
            display: flex;
            align-items: center;
            &-default {
                width: 100%;
                display: flex;
                justify-content: flex-end;
                padding: 0 10px;
                & > div {
                    margin: 0 8px;
                }
            }
        }
    }
}
</style>